package cn.mjnxin.iot.connector.coder;

import java.net.InetSocketAddress;

import cn.mjnxin.iot.base.cache.CountCache;
import cn.mjnxin.iot.base.constant.ConstantValue;
import cn.mjnxin.iot.base.domain.ChannelData;
import cn.mjnxin.iot.base.domain.GatePacketWriter;
import cn.mjnxin.iot.base.domain.SocketData;
import cn.mjnxin.iot.base.log.LogWorker;
import cn.mjnxin.iot.base.util.CommonUtil;
import cn.mjnxin.iot.connector.cache.HostRuntimeCache;
import cn.mjnxin.iot.transfer.TransferExchange;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;

/**
 * 编码器 将对象 编码成字节数组，目的地是网关
 * 
 * @author CLG 2023年10月10日
 * @version V1.0.0
 */
public class Host2GateEncoder extends MessageToByteEncoder<ChannelData> {
	// 日志等级 0：无日志 1：报文长度日志 2：报文内容日志 3：所有日志
	private int logLevel = 0;

	public Host2GateEncoder(int logLevel) {
		this.logLevel  = logLevel;
	}

	/**
	 * 当前ChannelHandlerContext 是与前置相连的channel的上下文
	 */
	@Override
	protected void encode(ChannelHandlerContext ctx, ChannelData msg, ByteBuf out) throws Exception {
		try {
			/**
			 * 组网关报头
			 */
			String ipAddress = msg.getTerminalAddress();

			SocketData data = msg.getSocketData();

			ByteBuf cliDataBuf = data.getByteBuf();
			cliDataBuf.readerIndex(0);
			int length = cliDataBuf.readableBytes();

			// 终端与网关建立连接时对应的连接序号（1-10000循环）
			final int count = data.getCount() == null ? CountCache.getCount() : data.getCount();
			GatePacketWriter headBuf = TransferExchange.packHead(HostRuntimeCache.gateNo, ConstantValue.TYPE_HOST_TO_TERMINAL, ipAddress, data.getPid(), logLevel, count, length);

			out.writeBytes(headBuf.getDataBuffer());
			// 真实报文
			out.writeBytes(cliDataBuf);
            InetSocketAddress insocket = (InetSocketAddress)ctx.channel().remoteAddress();
            String gateAddress = CommonUtil.getIpAddress(insocket);
            if (logLevel == 1) {
            	LogWorker.log(String.format("%d|T[%s]: H->G[%s]=%d Bytes", msg.getPid(), msg.getTerminalAddress(), gateAddress, out.readableBytes()));
            }
            else if (logLevel >= 2) {
            	LogWorker.log(String.format("%d|T[%s]: H->G[%s]=", msg.getPid(), msg.getTerminalAddress(), gateAddress), out);
            }
		} finally {
			CommonUtil.releaseData(msg);
		}
	}
}
